﻿using Micro.Core.Configs;
using Micro.Core.Packages;
using Micro.Extensions.SqlSugar.Base;
using Micro.Extensions.SqlSugar.UnitOfWork;
using Microsoft.AspNetCore.Builder;
using SqlSugar;
using SqlSugar.Extensions;

namespace Microsoft.Extensions.DependencyInjection
{
    public class SqlSugarPack : BasePackage
    {

        public override PackLevel Level => PackLevel.Framework;
        public override int Order => 20;

        public override IServiceCollection AddServices(IServiceCollection services)
        {
            AddSqlsugarSetup(services);
            services.AddScoped(typeof(IBaseRepository<>), typeof(BaseRepository<>));//注册仓储
            services.AddScoped<IUnitOfWork, UnitOfWork>();//工作单位
            return base.AddServices(services);
        }


        public override void UsePack(WebApplication app)
        {
            //app.
            base.UsePack(app);
        }


        private  void AddSqlsugarSetup(IServiceCollection services)
        {
            var microOption = services.GetMicroOptions();
            var dbConfig = microOption.DbConfig;
            var baseDbConfig = new BaseDBConfig(dbConfig);


            // 默认添加主数据库连接
            MainDb.CurrentDbConnId = dbConfig.MainDB.ObjToString().ToLower();

            // 把多个连接对象注入服务，这里必须采用Scope，因为有事务操作
            services.AddScoped<ISqlSugarClient>(o =>
            {
                // 连接字符串
                var listConfig = new List<ConnectionConfig>();
                // 从库
                var listConfig_Slave = new List<SlaveConnectionConfig>();
                baseDbConfig.SlaveDbs.ForEach(s =>
                {
                    listConfig_Slave.Add(new SlaveConnectionConfig()
                    {
                        HitRate = s.HitRate,
                        ConnectionString = s.Connection
                    });
                });

                baseDbConfig.AllDbs.ForEach(m =>
                {
                    listConfig.Add(new ConnectionConfig()
                    {
                        ConfigId = m.ConnId.ObjToString().ToLower(),
                        ConnectionString = m.Connection,
                        DbType = (DbType)m.DBType,
                        IsAutoCloseConnection = true,
                        //IsShardSameThread = false,
                        AopEvents = new AopEvents
                        {
                            OnLogExecuting = (sql, p) =>
                            {
                                Console.WriteLine("【SQL语句】：" + GetWholeSql(p, sql));

                            },
                        },
                        MoreSettings = new ConnMoreSettings()
                        {
                            //IsWithNoLockQuery = true,
                            IsAutoRemoveDataCache = true
                        },
                        // 从库
                        SlaveConnectionConfigs = listConfig_Slave,
                        // 自定义特性
                        ConfigureExternalServices = new ConfigureExternalServices()
                        {
                            EntityService = (property, column) =>
                            {
                                if (column.IsPrimarykey && property.PropertyType == typeof(int))
                                {
                                    column.IsIdentity = true;
                                }
                            }
                        },
                        InitKeyType = InitKeyType.Attribute


                    }
                   );
                });
                return new SqlSugarScope(listConfig);
            });
        }


        private string GetWholeSql(SugarParameter[] paramArr, string sql)
        {
            foreach (var param in paramArr)
            {
                sql.Replace(param.ParameterName, param.Value.ObjToString());
            }

            return sql;
        }

        private string GetParas(SugarParameter[] pars)
        {
            string key = "【SQL参数】：";
            foreach (var param in pars)
            {
                key += $"{param.ParameterName}:{param.Value}\n";
            }

            return key;
        }

    }
}